package com.mcxx.modules.temporary.service.impl;

import com.mcxx.common.exception.BizException;
import com.mcxx.constant.MQConstant;
import com.mcxx.modules.temporary.service.TempFundPayService;
import com.mcxx.modules.base.utils.QueryParamUtil;
import com.mcxx.modules.filemanage.easypoi.util.ExportExcelService;
import com.mcxx.modules.filemanage.file.service.FileService;
import com.mcxx.modules.miniSalvation.fundpay.dto.TempFundPayExcelDto;
import com.mcxx.modules.miniSalvation.fundpay.entity.FundpayExceptionEntity;
import com.mcxx.modules.miniSalvation.fundpay.param.FundPayParam;
import com.mcxx.modules.miniSalvation.fundpay.service.read.FundpayExceptionReadService;
import com.mcxx.modules.miniSalvation.fundpay.service.write.FundpayExceptionWriteService;
import com.mcxx.modules.system.dto.MQMessageDTO;
import com.mcxx.modules.system.entity.TaskExportEntity;
import com.mcxx.modules.system.service.write.TaskExportWriteService;
import com.mcxx.modules.temporary.fundpay.dto.TmpFundPayDTO;
import com.mcxx.modules.temporary.fundpay.dto.TmpFundPayFamilyDTO;
import com.mcxx.modules.temporary.fundpay.dto.TmpFundPayFamilyExcelDTO;
import com.mcxx.modules.temporary.fundpay.entity.TmpFundPayEntity;
import com.mcxx.modules.temporary.fundpay.param.TmpFundPayParam;
import com.mcxx.modules.temporary.fundpay.service.read.TmpFundPayFamilyReadService;
import com.mcxx.modules.temporary.fundpay.service.read.TmpFundPayReadService;
import com.mcxx.modules.temporary.fundpay.service.write.TmpFundPayFamilyWriteService;
import com.mcxx.modules.temporary.fundpay.service.write.TmpFundPayMemberWriteService;
import com.mcxx.modules.temporary.fundpay.service.write.TmpFundPayWriteService;
import com.mcxx.util.Constant;
import com.mcxx.util.FailureCode;
import com.mcxx.util.HttpServiceUtil;
import com.mcxx.util.OkHttpUtil;
import com.yinhai.ta404.component.audit.vo.ExcelInfo;
import com.yinhai.ta404.core.restservice.requestbean.PageParam;
import com.yinhai.ta404.core.restservice.resultbean.Page;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.service.BaseService;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;


@Slf4j
@Service
@TaTransactional
public class TempFundPayServiceImpl extends BaseService implements TempFundPayService {
    private static final Logger logger = LoggerFactory.getLogger(TempFundPayServiceImpl.class);
    @Autowired
    private TmpFundPayReadService tmpFundPayReadService;
    @Autowired
    private TmpFundPayWriteService tmpFundPayWriteService;
    @Autowired
    private TmpFundPayFamilyReadService tmpFundPayFamilyReadService;
    @Autowired
    private TmpFundPayFamilyWriteService tmpFundPayFamilyWriteService;
    @Autowired
    private TmpFundPayMemberWriteService tmpFundPayMemberWriteService;
    @Autowired
    private ExportExcelService exportExcelService;
    @Autowired
    private FileService fileService;
    @Autowired
    private TaskExportWriteService taskExportWriteService;
    @Autowired
    private FundpayExceptionReadService fundpayExceptionReadService;
    @Autowired
    private FundpayExceptionWriteService fundpayExceptionWriteService;

    @Value("${society.fundpay.tmpUrl:http://10.22.197.53:8011/mc-fundpay/base-info/updateSubsidyObjectAndBankAccountByMqyByTwo}")
    private String fundpayTempUrl;
    @Value("${society.fundpay.delUrl:http://10.22.197.53:8011/mc-fundpay/fund-pay-info/deleteFundPayByFundPayId}")
    private String fundpayDelUrl;


    @Override
    public void addFundPay(TmpFundPayDTO tmpFundPayDTO, UserAccountVo userAccountVo) {

        int count = tmpFundPayReadService.getFundPayNum(tmpFundPayDTO.getPayDate(), tmpFundPayDTO.getAreaCode(),
                                            tmpFundPayDTO.getPayWay(), Constant.FundPayState.CREATE_ING);
        if(count > 0){
            throw new BizException(FailureCode.ERR_100020);
        }


        tmpFundPayFamilyReadService.cntFamilyByCapital(tmpFundPayDTO, userAccountVo);


        tmpFundPayWriteService.insertCapital(tmpFundPayDTO, userAccountVo);
    }



    @Override
    public void confirmFundPay(String fundPayId, UserAccountVo userAccountVo) {

        List<String> stateList = new ArrayList<String>(){{add( Constant.FundPayState.CREATE); add( Constant.FundPayState.REVOKE);}};
        tmpFundPayReadService.isCanOperate(fundPayId, stateList);


        tmpFundPayWriteService.confirmFundPay(fundPayId, userAccountVo);
    }


    @Override
    public String checkCanSyncFundpayData(String fundPayId) {
        List<String> fundpayList = new ArrayList<>();
        fundpayList.add(fundPayId);
        TmpFundPayEntity fundPayEntity = tmpFundPayReadService.getById(fundPayId);
        String status = fundPayEntity.getStatus();
        String payType = fundPayEntity.getPayType();

        if(null == status || !Constant.FundPayState.CONFIRM.equals(status)) {
            return "该名册还未确认";
        }

        if(null != payType && "01".equals(payType)) {
            return "该名册不是银行转账";
        }

        boolean hasError = fundpayExceptionWriteService.checkAndConfirmException(fundPayId, Constant.BusinessCode.LINSHI);
        if(hasError) {
            return "该名册存在异常对象";
        }

        return null;
    }


    @Override
    public String syncFundpayData(String fundPayId) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("fundPayId", fundPayId);
        String retBody = OkHttpUtil.doPost(fundpayTempUrl, fundPayId);
        if(StringUtils.isNotEmpty(retBody)) {
            retBody = "同步发放名册失败:" + retBody;
        }
        logger.info("同步发放名册结果：{}", retBody);
        return retBody;
    }


    @Override
    public String delFundPay(List<String> fundPayIdList){
        StringBuffer msg = new StringBuffer();


        List<String> stateList = new ArrayList<String>(){{add(Constant.FundPayState.CREATE); add(Constant.FundPayState.REVOKE); add(Constant.FundPayState.CREATE_FAIL);}};
        Map<String, List<String>> rstMap = tmpFundPayReadService.getIdByIdAndStates(fundPayIdList, stateList);
        if(rstMap.containsKey("success") == false){

            return "待删除的名册不存在，请联系管理员";
        }

        for(String fundpayId : fundPayIdList) {
            String retMsg = HttpServiceUtil.httpCallDelFundpayData(fundpayDelUrl, fundpayId);
            if(StringUtils.isNotEmpty(retMsg)) {
                return "同步删除发放系统名册失败:" + retMsg;
            }
        }


        int rst = tmpFundPayWriteService.delFundPay(rstMap.get("success"));
        int count = 0;

        if(rst <= 0){

            return "名册删除失败";
        }
        else {
            count = fundpayExceptionWriteService.deleteByFundpayId(fundPayIdList);
            logger.info("删除名册相关的异常数据：{}", count);
        }

        return String.format("名册删除成功");
    }


    @Override
    public void delFundPayObjectList(String fundPayId, List<String> familyIdList) {


        tmpFundPayMemberWriteService.deleteFundPayMember(fundPayId, familyIdList);


        tmpFundPayFamilyWriteService.deleteByFundPayIdAndFamilyId(fundPayId, familyIdList);


        tmpFundPayWriteService.updateFundPayNum(fundPayId);
    }



    @Override
    public void addCapitalFundPayObject(TmpFundPayDTO tmpFundPayDTO, List<String> orderIdList) {

        List<String> stateList = new ArrayList<String>(){{add( Constant.FundPayState.CREATE); add( Constant.FundPayState.REVOKE);}};
        tmpFundPayReadService.isCanOperate(tmpFundPayDTO.getId(), stateList);


        tmpFundPayFamilyWriteService.saveCapitalFamilyByOrderId(orderIdList, tmpFundPayDTO);


        tmpFundPayWriteService.updateFundPayNum(tmpFundPayDTO.getId());
    }


    @Override
    public Page getNoSaveCapitalObjectList(TmpFundPayParam tmpFundPayParam, PageParam pageParam, UserAccountVo userAccountVo){

        QueryParamUtil.setBaseParamValue(tmpFundPayParam, userAccountVo);


        return  tmpFundPayFamilyReadService.getNoSaveCapitalFamilyList(tmpFundPayParam, pageParam);
    }


    @Override
    public ExcelInfo exportFundPayList(TmpFundPayParam param, UserAccountVo accountVo) {

        QueryParamUtil.setBaseParamValue(param, accountVo);


        List<TmpFundPayDTO>  list = tmpFundPayReadService.getFundPayList(param, accountVo);


        ExcelInfo excelInfo = exportExcelService.exportOrgOpLogs(TmpFundPayDTO.class,list,"临时救助资金发放名册信息.xls",
                "临时救助资金发放名册","临时救助资金发放名册",false,null);



        return excelInfo;
    }


    @Override
    public ExcelInfo exportCapitalList(TmpFundPayParam param, UserAccountVo accountVo) {

        QueryParamUtil.setBaseParamValue(param, accountVo);


        List<TmpFundPayFamilyDTO> list = tmpFundPayReadService.getTmpFundPayDetail(param,accountVo);


        ExcelInfo excelInfo = exportExcelService.exportOrgOpLogs(TmpFundPayFamilyDTO.class,list,"临时救助资金发放明细信息.xls",
                "临时救助资金发放明细","临时救助资金发放明细",false,null);


        if(null != excelInfo){
            InputStream sbs = new ByteArrayInputStream(excelInfo.getFile());
            String objectkey = fileService.upload(sbs,excelInfo.getFileName());
            if(StringUtils.isNotBlank(objectkey)){
                TaskExportEntity taskExport = new TaskExportEntity();
                taskExport.setId(Constant.getUUID());
                taskExport.setUserid(accountVo.getUserId());
                taskExport.setTaskName(excelInfo.getFileName());
                taskExport.setTaskTitle("临时救助资金发放列表");
                taskExport.setParam("xls");
                taskExport.setCreateTime(new Date());
                taskExport.setFileUrl(objectkey);
                taskExport.setState("02");
                int i = taskExportWriteService.insertIgnoreNull(taskExport);
                if(i > 0){
                    excelInfo = null;
                }
            }
        }
        return excelInfo;
    }


    @Override
    public String cancelFundPay(List<String> fundPayIdList){
        for(String fundpayId : fundPayIdList) {
            String retMsg = HttpServiceUtil.httpCallDelFundpayData(fundpayDelUrl, fundpayId);
            if(StringUtils.isNotEmpty(retMsg)) {
                return "同步删除发放系统名册失败:" + retMsg;
            }
        }

        int res = 0;
        if(!CollectionUtils.isEmpty(fundPayIdList)){
            for(String ids : fundPayIdList){
//                int i = tmpFundPayWriteService.updateFundPayStatus(ids, Constant.FundPayState.CREATE);
                int i = tmpFundPayWriteService.cancelTmpFundPay(ids, Constant.FundPayState.CREATE);
                if(i > 0){
                    res++;
                }
            }
        }
        return String.format("名册撤销成功");
    }


    @Override
    public Page<FundpayExceptionEntity> getPageFundpayException(String fundPayId, PageParam pageParam) {
        return fundpayExceptionReadService.getExceptionIdByTempFundpayId(fundPayId, pageParam);
    }


    @Override
    public ExcelInfo exportExcel(String fundpayId) {
        List<FundpayExceptionEntity> list = fundpayExceptionReadService.getExceptionByFundpayId(fundpayId);
        if(null==list || list.size() == 0) {
            return null;
        }
        ExcelInfo excelInfo = exportExcelService.exportOrgOpLogs(FundpayExceptionEntity.class,
                list,"临时救助发放名册异常信息表.xls",
                "临时救助发放名册异常信息表","名册对象",false,
                "street","community", "name","idcard","saveNumber","salaryNumber","bankName","bankAccount","remark");
        return excelInfo;
    }


    @Override
    public ExcelInfo exportCapitalObjectList(TmpFundPayParam param, UserAccountVo accountVo){
        ExcelInfo excelInfo = null;
        QueryParamUtil.setBaseParamValue(param,accountVo);



        List<TmpFundPayFamilyExcelDTO> list  = tmpFundPayFamilyReadService.exportCapitalObjectList(param);

        excelInfo = exportExcelService.exportOrgOpLogs(TmpFundPayFamilyExcelDTO.class,list,"临时救助发放名册明细信息.xls",
                "临时救助发放名册明细信息","临时救助发放名册明细信息",false,null);


        return excelInfo;
    }

    @Override
    public ExcelInfo exportExcelTempFundPay(String exportType, List<String> idsList, FundPayParam param, UserAccountVo accountVo) {
        QueryParamUtil.setBaseParamValue(param,accountVo);

        param.setIdsList(idsList);
        List<TempFundPayExcelDto> list = tmpFundPayReadService.exportExcelTempFundPay(param);
        ExcelInfo excelInfo = exportExcelService.exportOrgOpLogs(TempFundPayExcelDto.class,list,"临时救助资金发放名册信息.xls",
                "临时救助资金发放名册列表","临时救助资金发放名册列表",false,"payDate","payType","commitDate",
                "isAuto","payWay","households","standType","fundName");


        return excelInfo;
    }

}
